package com.hubei.car.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hubei.car.constant.RedisKeyCode;
import com.hubei.car.constant.StatusCode;
import com.hubei.car.entity.CarThirdUser;
import com.hubei.car.entity.MsProduct;
import com.hubei.car.entity.Result;
import com.hubei.car.handler.BaseException;
import com.hubei.car.mapper.CarThirdUserMapper;
import com.hubei.car.mapper.MsProductMapper;
import com.hubei.car.service.CarThirdLoginService;
import com.hubei.car.service.MsProductService;
import com.hubei.car.swaggerParam.CarThirdUserUpdateParam;
import com.hubei.car.utils.HttpUtil;
import com.hubei.car.utils.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * 第三方登录辅助类
 *
 * @author luokangtao
 * @create 2019-09-03 10:58
 */
@Slf4j
@Service
public class CarThirdLoginServiceImpl implements CarThirdLoginService {
    @Autowired
    private CarThirdUserMapper carThirdUserMapper;
    @Autowired
    private MsProductMapper msProductMapper;
    @Autowired
    private JwtUtil jwtUtil;
    @Autowired
    private RedisTemplate redisTemplate;

    @Value("${app_id_wx}")
    private String AppIdWX;//申请成功之后你会得到appId和appKey
    @Value("${app_key_wx}")
    private String AppKeyWX;
    @Value("${accessTokenURL_wx}")
    private String AccessTokenURLWX;//根据code 获取token和openid
    @Value("${getUserInfoURL_wx}")
    private String GETUserInfoURLWX;//根据token和openid 获取微信用户相关信息

    @Value("${wechat_sessionHost}")
    private String WechatSessionHost;
    @Value("${wechat_appId}")
    private String WechatAppId;
    @Value("${wechat_secret}")
    private String WechatSecret;
    @Value("${wechat_grantType}")
    private String WechatGrantType;


    /**
     * 根据code获取微信的认证token和用户OpenID
     */
    @Override
    public Map<String, String> getWxTokenAndOpenid(String code) {
        Map<String, String> map = new HashMap<String, String>();
        // 获取令牌地址 accessTokenURL_wx=https://api.weixin.qq.com/sns/oauth2/access_token
        String tokenUrl = AccessTokenURLWX + "?appid=" + AppIdWX + "&secret=" + AppKeyWX + "&code=" + code + "&grant_type=authorization_code";
        //http的post请求
        String tokenRes = HttpUtil.httpClientPost(tokenUrl);
        //返回的 access_token 不能空
        if (tokenRes != null && tokenRes.indexOf("access_token") > -1) {
            //将格式为s1&s2&s3...的字符串转化成Map集合
            Map<String, String> parse = toMap(tokenRes);
            //获取access_token
            map.put("access_token", parse.get("access_token"));
            // 获取微信用户的唯一标识openid
            map.put("openId", parse.get("openid"));
        } else {
            System.out.println(tokenRes);
            throw new BaseException("微信登陆失败");
        }
        //返回结果集 access_token 和 openId
        return map;
    }

    /**
     * 将格式为s1&s2&s3...的字符串转化成Map集合
     *
     * @param str
     * @return
     */
    private static final Map<String, String> toMap(String str) {
        Map<String, String> map = new HashMap<String, String>();
        String[] strs = str.split("&");
        for (int i = 0; i < strs.length; i++) {
            String[] ss = strs[i].split("=");
            map.put(ss[0], ss[1]);
        }
        return map;
    }

    /**
     * 获取微信用户信息
     */
    @Override
    public CarThirdUser getWxUserinfo(String token, String openid) {
        //组装第三方用户实体类
        CarThirdUser user = new CarThirdUser();
        //获取微信用户信息 getUserInfoURL_wx=https://api.weixin.qq.com/sns/userinfo
        String url = GETUserInfoURLWX + "?access_token=" + token + "&openid=" + openid;
        //http的post请求
        String res = HttpUtil.httpClientPost(url);
        //String类型转成对象类型
        JSONObject json = JSONObject.parseObject(res);
        //errcode等于null
        if (json.getString("errcode") == null) {
            //用户昵称 nickname
            user.setAliasname(json.getString("nickname"));
            //用户头像地址 headimgurl
            String img = json.getString("headimgurl");
            if (img != null && !"".equals(img)) {
                user.setAvatarurl(img);
            }
            //用户性别 headimgurl
            String sex = json.getString("sex");
            if ("0".equals(sex)) {
                user.setSex("0");
            } else {
                user.setSex("1");
            }
        } else {
            //如果出错则抛出异常
            throw new IllegalArgumentException(json.getString("errmsg"));
        }
        return user;
    }

    @Override
    @Transactional
    public CarThirdUser thirdPartyLogin(CarThirdUser thirdUser) {
        //根据openid查询当前数据库是否存在
        QueryWrapper<CarThirdUser> querywrapper = new QueryWrapper<>();
        querywrapper.eq("openid", thirdUser.getOpenid());
        CarThirdUser user = carThirdUserMapper.selectOne(querywrapper);
        if (!ObjectUtils.isEmpty(user)) {
            //更新微信数据
            thirdUser.setId(user.getId());
            carThirdUserMapper.updateById(thirdUser);
        } else {
            //如果数据库没有则插入数据库
            thirdUser.setCreateTime(LocalDateTime.now());
            thirdUser.setRoles("0");
            carThirdUserMapper.insert(thirdUser);
        }
        //生成登陆token
        String adminString = JSONObject.toJSONString(thirdUser);//用户信息对象转成json
        log.info("把第三方用户信息转成字符串:[{}]", adminString);

        //登录成功,生成token   参数1:用户登陆名  参数2:用户实体类  参数3:角色
        String token = jwtUtil.createJWT(thirdUser.getOpenid(), adminString, thirdUser.getRoles().equals("0") ? "common" : thirdUser.getRoles().equals("1") ? "admin" : "superadmin", "wx");
        // key = <用户登陆名,生成token>
        redisTemplate.boundHashOps(RedisKeyCode.LOGIN).put(thirdUser.getOpenid(), token);
        //登陆token
        thirdUser.setToken(token);
        //返回结果集
        return thirdUser;
    }

    @Override
    public Map<String, String> getWechatAndOpenid(String code) {
        //GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
        String url = "appid=" + WechatAppId + "&secret=" + WechatSecret+"&js_code="+code+"&grant_type="+WechatGrantType;
        String clientPost = HttpUtil.sendGet(WechatSessionHost, url);
        JSONObject object = JSONObject.parseObject(clientPost);
        log.info("微信小程序=>根据code换取openid和session_key远程调用返回对象解析:[{}]",object);
        Map<String,String> map;
        //0是请求成功
        if (object.getIntValue("errcode") == 0) {
            map = new HashMap<>();
            map.put("openId", object.getString("openid"));
            map.put("sessionKey", object.getString("session_key"));
        } else {
            throw new BaseException("微信小程序登陆失败");
        }
        return map;
    }

    @Override
    public CarThirdUser getWechatUserinfo(String decrypts,CarThirdUser carThirdUser) {
        JSONObject jsons = JSONObject.parseObject(decrypts);
        carThirdUser.setSex(jsons.getString("gender"));//性别
        carThirdUser.setAliasname(jsons.getString("nickName"));//用户昵称
        carThirdUser.setAvatarurl(jsons.getString("avatarUrl"));//用户头像
        //根据openid查询当前数据库是否存在
        QueryWrapper<CarThirdUser> querywrapper = new QueryWrapper<>();
        querywrapper.eq("openid", carThirdUser.getOpenid());
        CarThirdUser carThirdUserDB = carThirdUserMapper.selectOne(querywrapper);
        if (!ObjectUtils.isEmpty(carThirdUserDB)) {
            //更新微信数据
            carThirdUser.setId(carThirdUserDB.getId());
            carThirdUserMapper.updateById(carThirdUser);
        } else {
            //如果数据库没有则插入数据库
            carThirdUser.setCreateTime(LocalDateTime.now());
            carThirdUser.setRoles("0");
            carThirdUserMapper.insert(carThirdUser);
        }
        //生成登陆token
        String adminString = JSONObject.toJSONString(carThirdUser);//用户信息对象转成json
        log.info("把第三方用户信息转成字符串:[{}]", adminString);
        String roleName = "superadmin";
        switch (carThirdUser.getRoles()) {
            case "0": roleName = "common";
            case "1": roleName = "admin";
        }
        //生成token   参数1:用户登陆名  参数2:用户实体类  参数3:角色
        String token = jwtUtil.createJWT(carThirdUser.getOpenid(), adminString, roleName, "wx");
        // key = <用户登陆名,生成token>
        redisTemplate.boundHashOps(RedisKeyCode.LOGIN).put(carThirdUser.getOpenid(), token);
        //登陆token
        carThirdUser.setToken(token);
        //返回结果集
        return carThirdUser;
    }

    @Override
    public CarThirdUser queryMyInfo(Long id) {
        if (id == null) {
            return null;
        }
        CarThirdUser carThirdUser = carThirdUserMapper.selectById(id);
        if (carThirdUser == null) {
            return null;
        }
        if (carThirdUser.getMsProductId() != null){
            MsProduct msProduct = msProductMapper.selectById(carThirdUser.getMsProductId());
            if (msProduct != null)
            carThirdUser.setMsProductName(msProduct.getName());
        }
        return carThirdUser;
    }

    @Transactional
    @Override
    public Result updateMyInfo(CarThirdUserUpdateParam carThirdUserUpdateParam, CarThirdUser carThirdUser) {
        CarThirdUser carThirdUserDB = carThirdUserMapper.selectById(carThirdUser.getId());
        if (StrUtil.isNotBlank(carThirdUserUpdateParam.getAddress())) {
            carThirdUserDB.setAddress(carThirdUserUpdateParam.getAddress());
        }
        if (StrUtil.isNotBlank(carThirdUserUpdateParam.getMobile())) {
            carThirdUserDB.setMobile(carThirdUserUpdateParam.getMobile());
        }
        if (StrUtil.isNotBlank(carThirdUserUpdateParam.getRealName())) {
            carThirdUserDB.setRealName(carThirdUserUpdateParam.getRealName());
        }
        if (carThirdUserUpdateParam.getMsProductId() != null) {
            carThirdUserDB.setMsProductId(carThirdUserUpdateParam.getMsProductId());
        }
        if (StrUtil.isNotBlank(carThirdUserUpdateParam.getAvatarurl())) {
            carThirdUserDB.setAvatarurl(carThirdUserUpdateParam.getAvatarurl());
        }
        if (StrUtil.isNotBlank(carThirdUserUpdateParam.getSex())) {
            carThirdUserDB.setSex(carThirdUserUpdateParam.getSex());
        }
        if (StrUtil.isNotBlank(carThirdUserUpdateParam.getNickName())) {
            carThirdUserDB.setAliasname(carThirdUserUpdateParam.getNickName());
        }
        carThirdUserMapper.updateById(carThirdUserDB);
        return Result.ok("修改成功");
    }

    @Override
    public CarThirdUser getCarThirdUser(String openid) {
        //根据openid查询当前数据库是否存在
        QueryWrapper<CarThirdUser> querywrapper = new QueryWrapper<>();
        querywrapper.eq("openid", openid);
        CarThirdUser user = carThirdUserMapper.selectOne(querywrapper);
        //如果不存在则添加小程序用户
        if (ObjectUtils.isEmpty(user)) {
            //如果数据库没有则插入数据库
            user = new CarThirdUser();
            user.setCreateTime(LocalDateTime.now());
            user.setRoles("0");
            user.setOpenid(openid);
            carThirdUserMapper.insert(user);
        }
        return user;
    }
}
